package com.weimob.mcloud.wechatwork.customer.job;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.weimob.elasticjob.annotation.ElasticJob;
import com.weimob.elasticjob.executor.context.ExecutorContext;
import com.weimob.mcloud.wechatwork.core.entity.privatesphere.PrivateSphere;
import com.weimob.mcloud.wechatwork.core.entity.relation.tag.CustomerTag;
import com.weimob.mcloud.wechatwork.core.entity.relation.tag.Tag;
import com.weimob.mcloud.wechatwork.core.entity.relation.tag.TagGroup;
import com.weimob.mcloud.wechatwork.core.service.privatesphere.PrivateSphereService;
import com.weimob.mcloud.wechatwork.customer.mq.product.TagChangeMsgProduct;
import com.weimob.mcloud.wechatwork.customer.service.CustomerEmployeeTagService;
import com.weimob.mcloud.wechatwork.customer.service.TagBaseService;
import com.weimob.mcloud.wechatwork.customer.service.TagManageService;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.v2.CorpTagDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.v2.CorpTagGroupDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.msgBody.CorpCustomerTagChangeBody;
import com.weimob.mcloud.wechatwork.customer.third.customer.CustomerThird;
import com.weimob.soa.common.response.SoaResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

@Slf4j
@Component
public class EmployeeCustomerTagJob {

    @Autowired
    private TagManageService tagManageService;

    @Autowired
    private CustomerEmployeeTagService customerEmployeeTagService;

    @Autowired
    private TagBaseService tagBaseService;

    @Autowired
    private TagChangeMsgProduct tagChangeMsgProduct;

    @Reference
    private PrivateSphereService privateSphereService;

    @Autowired
    private CustomerThird customerThird;

    /**
     * 同步员工&客户&标签关系数据到企微助手，企微助手db里面的标签数据与查询到腾讯返回的数据做差值对比，同步到cdp
     *
     * 主要逻辑：
     * 1、根据externalUserId查询腾讯客户详情
     * 2、企微助手db表customer_employee_tag、corp_customer_tag落数据
     * 3、同步cdp
     * @param context
     */
    @ElasticJob(name = "syncEmployeeCustomerTagFromTX", cron = "0 0 0 30 12 ? 2099")
    public void syncEmployeeCustomerTagFromQW(ExecutorContext context) {
        Map<String, String> customParameter = context.getTriggerCustomParameter();
        if (MapUtils.isEmpty(customParameter)) {
            return;
        }

        log.info("触发员工客户标签信息同步, request:{}", JSON.toJSONString(customParameter));
        String bosId = customParameter.get("bosId");
        if (StringUtils.isBlank(bosId)) {
            return;
        }

        PrivateSphere request = new PrivateSphere();
        request.setBosId(Long.parseLong(bosId));
        request.setProductId(203L);
        SoaResponse<PrivateSphere, Void> sphereVoidSoaResponse = privateSphereService.fetch(request);
        if (0L != Long.parseLong(sphereVoidSoaResponse.getReturnCode())) {
            return;
        }
        PrivateSphere privateSphere = sphereVoidSoaResponse.getResponseVo();

        String externalUserIdStr = customParameter.get("externalUserIdStr");
        if (Objects.isNull(privateSphere) || StringUtils.isBlank(externalUserIdStr)) {
            return;
        }

        String[] externalUserIds = externalUserIdStr.split(",");

        for (String externalUserId : externalUserIds) {
            if (StringUtils.isBlank(externalUserId)) {
                continue;
            }

            try {

                tagManageService.initCustomerTag(privateSphere, externalUserId, null);
            } catch (Exception e) {
                log.error("手动同步员工&客户&标签关系失败, externalUserId:{}, error:{}", externalUserId, e.getMessage());
            }

        }

    }

    /**
     * 同步客户标签关系到cdp
     *
     * 关键步骤
     *
     * 1、查询企微助手db表corp_customer_tag数据
     * 2、往cdp同步
     * @param context
     */
    @ElasticJob(name = "syncCustomerTag2CDPFromQW", cron = "0 0 0 30 12 ? 2099")
    public void syncCustomerTag2CDPFromQW(ExecutorContext context) {
        Map<String, String> customParameter = context.getTriggerCustomParameter();
        if (MapUtils.isEmpty(customParameter)) {
            return;
        }

        log.info("触发同步客户标签关系数据到cdp, request:{}", JSON.toJSONString(customParameter));

        String corpId = customParameter.get("corpId");
        String externalUserIdStr = customParameter.get("externalUserIdStr");
        if (StringUtils.isBlank(corpId) || StringUtils.isBlank(externalUserIdStr)) {
            return;
        }

        PrivateSphere request = new PrivateSphere();
        request.setCorpId(corpId);
        request.setProductId(203L);
        SoaResponse<PrivateSphere, Void> soaResponse = privateSphereService.fetch(request);
        if (0L != Long.parseLong(soaResponse.getReturnCode())) {
            log.error("查询私域失败, corpId:{}, error:{}", corpId, soaResponse.getReturnMsg());
            return;
        }

        PrivateSphere privateSphere = soaResponse.getResponseVo();

        String[] externalUserIds = externalUserIdStr.split(",");
        for (String externalUserId : externalUserIds) {
            if (StringUtils.isBlank(externalUserId)) {
                continue;
            }

            try {
                CustomerTag customerTag = customerEmployeeTagService.getCustomerTag(privateSphere, externalUserId);
                if (null == customerTag || CollectionUtils.isEmpty(customerTag.getTagIds())) {
                    return;
                }

                Long customerWid = customerThird.getSuperWid(privateSphere.getBosId(), externalUserId, privateSphere.getCorpId());
                if (null == customerWid) {
                    log.error("客户标签同步，查询passport获取wid失败, externalUserId:{}", externalUserId);
                    return;
                }

                sendCustomerTagChangeMsg(privateSphere, customerWid, externalUserId, customerTag.getTagIds(), null);
            } catch (Exception e) {
                log.error("手动同步客户标签关系数据到cdp失败, externalUserId:{}, error:{}", externalUserId, e.getMessage());
            }

        }
    }

    /**
     * 移除客户标签关系，同步到cdp
     * @param context
     */
    @ElasticJob(name = "syncRemoveCustomerTag2CDPFromQW", cron = "0 0 0 30 12 ? 2099")
    public void syncRemoveCustomerTag2CDPFromQW(ExecutorContext context){
        Map<String, String> customParameter = context.getTriggerCustomParameter();
        if (MapUtils.isEmpty(customParameter)) {
            return;
        }

        log.info("触发同步移除客户标签关系数据到cdp, request:{}", JSON.toJSONString(customParameter));

        String corpId = customParameter.get("corpId");
        String externalUserId = customParameter.get("externalUserId");
        String removeTagIdStr = customParameter.get("removeTagIdStr");
        if (StringUtils.isBlank(corpId) || StringUtils.isBlank(externalUserId) || StringUtils.isBlank(removeTagIdStr)) {
            return;
        }

        PrivateSphere request = new PrivateSphere();
        request.setCorpId(corpId);
        request.setProductId(203L);
        SoaResponse<PrivateSphere, Void> soaResponse = privateSphereService.simpleFetch(request);
        if (0L != Long.parseLong(soaResponse.getReturnCode())) {
            log.error("查询私域失败, corpId:{}, error:{}", corpId, soaResponse.getReturnMsg());
            return;
        }

        PrivateSphere privateSphere = soaResponse.getResponseVo();

        Long customerWid = customerThird.getSuperWid(privateSphere.getBosId(), externalUserId, privateSphere.getCorpId());
        if (null == customerWid) {
            log.error("客户标签同步，查询passport获取wid失败, externalUserId:{}", externalUserId);
            return;
        }

        String[] tagIds = removeTagIdStr.split(",");
        Set<String> tagIdSet = new HashSet<>();
        for (String tagId : tagIds) {
            if (StringUtils.isBlank(tagId)) {
                continue;
            }
            tagIdSet.add(tagId);
        }

        sendCustomerTagChangeMsg(privateSphere, customerWid, externalUserId, null, tagIdSet);
    }

    private void sendCustomerTagChangeMsg(PrivateSphere privateSphere, Long wid, String externalUserId,
                                          Set<String> addTagIds, Set<String> removeTagIds) {
        if (null == privateSphere || null == wid || StringUtils.isBlank(externalUserId)) {
            return;
        }

        if (CollectionUtils.isEmpty(addTagIds) && CollectionUtils.isEmpty(removeTagIds)) {
            return;
        }

        Set<String> allTagIds = new HashSet<>();
        if (CollectionUtils.isNotEmpty(addTagIds)) {
            allTagIds.addAll(addTagIds);
        }
        if (CollectionUtils.isNotEmpty(removeTagIds)) {
            allTagIds.addAll(removeTagIds);
        }

        //根据标签id查询标签组
        List<Tag> tagList = tagBaseService.queryTagByTagIds(privateSphere.getCorpId(), Lists.newArrayList(allTagIds), true);
        if (CollectionUtils.isEmpty(tagList)) {
            log.warn("同步cdp客户标签变更, 查询标签不存在, corpId:{}, tagIds:{}", privateSphere.getCorpId(), JSON.toJSONString(allTagIds));
            return;
        }

        Map<String, String> tagIdAndGroupIdMap = toTagIdAndGroupIdMap(tagList);

        //构建需要添加的标签对象
        List<CorpTagDTO> addCorpTagDTOS = buildCorpTagDTOList(addTagIds, tagIdAndGroupIdMap);

        //构建需要移除的标签对象
        List<CorpTagDTO> removeCorpTagDTOS = buildCorpTagDTOList(removeTagIds, tagIdAndGroupIdMap);


        CorpCustomerTagChangeBody corpCustomerTagChangeBody = new CorpCustomerTagChangeBody();
        corpCustomerTagChangeBody.setBosId(privateSphere.getBosId());
        corpCustomerTagChangeBody.setCorpId(privateSphere.getCorpId());
        corpCustomerTagChangeBody.setExternalUserId(externalUserId);
        corpCustomerTagChangeBody.setWid(wid);
        corpCustomerTagChangeBody.setAddTagList(addCorpTagDTOS);
        corpCustomerTagChangeBody.setRemoveTagList(removeCorpTagDTOS);

        //同步cdp添加客户标签关系
        tagChangeMsgProduct.sendCorpCustomerTagChangeBody(corpCustomerTagChangeBody);
    }

    private Map<String, String> toTagIdAndGroupIdMap(List<Tag> tagIdList) {
        if (CollectionUtils.isEmpty(tagIdList)) {
            return new HashMap<>();
        }

        Map<String, String> tagIdAndGroupIdMap = new HashMap<>();
        for (Tag tag : tagIdList) {
            TagGroup tagGroup = tag.getTagGroup();
            if (null == tagGroup) {
                continue;
            }

            tagIdAndGroupIdMap.put(tag.getExternalTagId(), tagGroup.getExternalTagGroupId());
        }

        return tagIdAndGroupIdMap;
    }

    private List<CorpTagDTO> buildCorpTagDTOList(Set<String> tagIds, Map<String, String> tagIdAndGroupIdMap) {
        if (CollectionUtils.isEmpty(tagIds) || MapUtils.isEmpty(tagIdAndGroupIdMap)) {
            return new ArrayList<>();
        }

        List<CorpTagDTO> list = new ArrayList<>();
        for (String tagId : tagIds) {
            String groupId = tagIdAndGroupIdMap.get(tagId);
            if (StringUtils.isBlank(groupId)) {
                continue;
            }

            CorpTagDTO corpTagDTO = new CorpTagDTO();
            corpTagDTO.setCorpTagId(tagId);

            CorpTagGroupDTO tagGroupDTO = new CorpTagGroupDTO();
            tagGroupDTO.setCorpTagGroupId(groupId);
            corpTagDTO.setTagGroupDTO(tagGroupDTO);

            list.add(corpTagDTO);
        }

        return list;
    }

}
